import 'dart:io';
import 'package:get/get.dart';
import 'package:path/path.dart' as path;
import 'package:mime/mime.dart';

import '../models/virtual_file_node.dart';
import '../models/file_metadata.dart';
import 'database_service.dart';
import 'tianyi_cloud_service.dart';

class FileManagerService extends GetxService {
  final DatabaseService _databaseService = Get.find<DatabaseService>();
  final TianyiCloudService _cloudService = Get.find<TianyiCloudService>();
  
  // 当前目录
  final RxString _currentPath = '/'.obs;
  String get currentPath => _currentPath.value;
  
  // 当前目录的文件列表
  final RxList<VirtualFileNode> _currentFiles = <VirtualFileNode>[].obs;
  List<VirtualFileNode> get currentFiles => _currentFiles;
  
  // 选中的文件
  final RxList<VirtualFileNode> _selectedFiles = <VirtualFileNode>[].obs;
  List<VirtualFileNode> get selectedFiles => _selectedFiles;
  
  // 加载状态
  final RxBool _isLoading = false.obs;
  bool get isLoading => _isLoading.value;
  
  @override
  Future<void> onInit() async {
    super.onInit();
    await loadCurrentDirectory();
  }
  
  // 加载当前目录
  Future<void> loadCurrentDirectory() async {
    _isLoading.value = true;
    try {
      final currentNode = await _databaseService.getVirtualFileNodeByPath(_currentPath.value);
      if (currentNode != null) {
        final children = await _databaseService.getChildrenByParentId(currentNode.id);
        _currentFiles.value = children;
      } else {
        _currentFiles.clear();
      }
    } catch (e) {
      print('加载目录失败: $e');
      _currentFiles.clear();
    } finally {
      _isLoading.value = false;
    }
  }
  
  // 进入目录
  Future<void> enterDirectory(VirtualFileNode node) async {
    if (node.isFolder) {
      _currentPath.value = node.path;
      await loadCurrentDirectory();
      _selectedFiles.clear();
    }
  }
  
  // 返回上级目录
  Future<void> goBack() async {
    if (_currentPath.value != '/') {
      final parentPath = path.dirname(_currentPath.value);
      _currentPath.value = parentPath == '.' ? '/' : parentPath;
      await loadCurrentDirectory();
      _selectedFiles.clear();
    }
  }
  
  // 导航到指定路径
  Future<void> navigateToPath(String targetPath) async {
    _currentPath.value = targetPath;
    await loadCurrentDirectory();
    _selectedFiles.clear();
  }
  
  // 创建文件夹
  Future<VirtualFileNode> createFolder(String folderName) async {
    final currentNode = await _databaseService.getVirtualFileNodeByPath(_currentPath.value);
    if (currentNode == null) {
      throw Exception('当前目录不存在');
    }
    
    final folderPath = path.join(_currentPath.value, folderName);
    
    // 检查是否已存在
    final existingNode = await _databaseService.getVirtualFileNodeByPath(folderPath);
    if (existingNode != null) {
      throw Exception('文件夹已存在');
    }
    
    final newFolder = VirtualFileNode(
      name: folderName,
      type: NodeType.folder,
      parentId: currentNode.id,
      path: folderPath,
      createdTime: DateTime.now(),
      updatedTime: DateTime.now(),
    );
    
    final id = await _databaseService.insertVirtualFileNode(newFolder);
    final createdFolder = newFolder.copyWith(id: id);
    
    await loadCurrentDirectory();
    return createdFolder;
  }
  
  // 添加文件到虚拟文件系统
  Future<VirtualFileNode> addFileToVirtualSystem(
    String fileName,
    String fileMd5,
    String targetPath,
  ) async {
    // 获取目标目录节点
    final targetDir = await _databaseService.getVirtualFileNodeByPath(targetPath);
    if (targetDir == null || !targetDir.isFolder) {
      throw Exception('目标目录不存在');
    }
    
    final filePath = path.join(targetPath, fileName);
    
    // 检查是否已存在
    final existingNode = await _databaseService.getVirtualFileNodeByPath(filePath);
    if (existingNode != null) {
      throw Exception('文件已存在');
    }
    
    final newFile = VirtualFileNode(
      name: fileName,
      type: NodeType.file,
      parentId: targetDir.id,
      fileMd5: fileMd5,
      path: filePath,
      createdTime: DateTime.now(),
      updatedTime: DateTime.now(),
    );
    
    final id = await _databaseService.insertVirtualFileNode(newFile);
    final createdFile = newFile.copyWith(id: id);
    
    // 如果是当前目录，刷新列表
    if (targetPath == _currentPath.value) {
      await loadCurrentDirectory();
    }
    
    return createdFile;
  }
  
  // 重命名文件或文件夹
  Future<void> rename(VirtualFileNode node, String newName) async {
    final newPath = path.join(path.dirname(node.path), newName);
    
    // 检查新名称是否已存在
    final existingNode = await _databaseService.getVirtualFileNodeByPath(newPath);
    if (existingNode != null && existingNode.id != node.id) {
      throw Exception('名称已存在');
    }
    
    final updatedNode = node.copyWith(
      name: newName,
      path: newPath,
      updatedTime: DateTime.now(),
    );
    
    await _databaseService.updateVirtualFileNode(updatedNode);
    
    // 如果是文件夹，需要更新所有子节点的路径
    if (node.isFolder) {
      await _updateChildrenPaths(node.path, newPath);
    }
    
    await loadCurrentDirectory();
  }
  
  // 更新子节点路径
  Future<void> _updateChildrenPaths(String oldParentPath, String newParentPath) async {
    final children = await _databaseService.getChildrenByParentId(
      (await _databaseService.getVirtualFileNodeByPath(newParentPath))?.id
    );
    
    for (final child in children) {
      final newChildPath = child.path.replaceFirst(oldParentPath, newParentPath);
      final updatedChild = child.copyWith(
        path: newChildPath,
        updatedTime: DateTime.now(),
      );
      
      await _databaseService.updateVirtualFileNode(updatedChild);
      
      // 递归更新子文件夹
      if (child.isFolder) {
        await _updateChildrenPaths(child.path, newChildPath);
      }
    }
  }
  
  // 删除文件或文件夹（移到回收站）
  Future<void> delete(VirtualFileNode node) async {
    await _databaseService.deleteVirtualFileNode(node.id!);
    
    // 如果是文件夹，递归删除所有子节点
    if (node.isFolder) {
      await _deleteChildren(node.id!);
    }
    
    await loadCurrentDirectory();
    _selectedFiles.remove(node);
  }
  
  // 递归删除子节点
  Future<void> _deleteChildren(int parentId) async {
    final children = await _databaseService.getChildrenByParentId(parentId);
    for (final child in children) {
      await _databaseService.deleteVirtualFileNode(child.id!);
      if (child.isFolder) {
        await _deleteChildren(child.id!);
      }
    }
  }
  
  // 移动文件或文件夹
  Future<void> move(VirtualFileNode node, String targetPath) async {
    final targetDir = await _databaseService.getVirtualFileNodeByPath(targetPath);
    if (targetDir == null || !targetDir.isFolder) {
      throw Exception('目标目录不存在');
    }
    
    final newPath = path.join(targetPath, node.name);
    
    // 检查目标位置是否已存在同名文件
    final existingNode = await _databaseService.getVirtualFileNodeByPath(newPath);
    if (existingNode != null) {
      throw Exception('目标位置已存在同名文件');
    }
    
    final updatedNode = node.copyWith(
      parentId: targetDir.id,
      path: newPath,
      updatedTime: DateTime.now(),
    );
    
    await _databaseService.updateVirtualFileNode(updatedNode);
    
    // 如果是文件夹，需要更新所有子节点的路径
    if (node.isFolder) {
      await _updateChildrenPaths(node.path, newPath);
    }
    
    await loadCurrentDirectory();
  }
  
  // 复制文件或文件夹
  Future<void> copy(VirtualFileNode node, String targetPath) async {
    final targetDir = await _databaseService.getVirtualFileNodeByPath(targetPath);
    if (targetDir == null || !targetDir.isFolder) {
      throw Exception('目标目录不存在');
    }
    
    await _copyNode(node, targetDir.id!, targetPath);
    
    // 如果目标是当前目录，刷新列表
    if (targetPath == _currentPath.value) {
      await loadCurrentDirectory();
    }
  }
  
  // 递归复制节点
  Future<void> _copyNode(VirtualFileNode node, int targetParentId, String targetParentPath) async {
    final newPath = path.join(targetParentPath, node.name);
    
    // 如果目标位置已存在同名文件，生成新名称
    String finalName = node.name;
    String finalPath = newPath;
    int counter = 1;
    
    while (await _databaseService.getVirtualFileNodeByPath(finalPath) != null) {
      if (node.isFolder) {
        finalName = '${node.name}_副本$counter';
      } else {
        final extension = path.extension(node.name);
        final nameWithoutExt = path.basenameWithoutExtension(node.name);
        finalName = '${nameWithoutExt}_副本$counter$extension';
      }
      finalPath = path.join(targetParentPath, finalName);
      counter++;
    }
    
    final copiedNode = VirtualFileNode(
      name: finalName,
      type: node.type,
      parentId: targetParentId,
      fileMd5: node.fileMd5,
      path: finalPath,
      createdTime: DateTime.now(),
      updatedTime: DateTime.now(),
    );
    
    final newId = await _databaseService.insertVirtualFileNode(copiedNode);
    
    // 如果是文件夹，递归复制子节点
    if (node.isFolder) {
      final children = await _databaseService.getChildrenByParentId(node.id);
      for (final child in children) {
        await _copyNode(child, newId, finalPath);
      }
    }
  }
  
  // 获取文件元数据
  Future<FileMetadata?> getFileMetadata(VirtualFileNode node) async {
    if (node.isFile && node.fileMd5 != null) {
      return await _databaseService.getFileMetadataByMd5(node.fileMd5!);
    }
    return null;
  }
  
  // 搜索文件
  Future<List<VirtualFileNode>> searchFiles(String keyword) async {
    // 这里简化实现，实际应该在数据库层面进行搜索
    final allFiles = <VirtualFileNode>[];
    await _collectAllFiles('/', allFiles);
    
    return allFiles.where((file) => 
      file.name.toLowerCase().contains(keyword.toLowerCase())
    ).toList();
  }
  
  // 收集所有文件（递归）
  Future<void> _collectAllFiles(String dirPath, List<VirtualFileNode> result) async {
    final dir = await _databaseService.getVirtualFileNodeByPath(dirPath);
    if (dir != null) {
      final children = await _databaseService.getChildrenByParentId(dir.id);
      for (final child in children) {
        result.add(child);
        if (child.isFolder) {
          await _collectAllFiles(child.path, result);
        }
      }
    }
  }
  
  // 选择/取消选择文件
  void toggleSelection(VirtualFileNode node) {
    if (_selectedFiles.contains(node)) {
      _selectedFiles.remove(node);
    } else {
      _selectedFiles.add(node);
    }
  }
  
  // 全选/取消全选
  void toggleSelectAll() {
    if (_selectedFiles.length == _currentFiles.length) {
      _selectedFiles.clear();
    } else {
      _selectedFiles.value = List.from(_currentFiles);
    }
  }
  
  // 清除选择
  void clearSelection() {
    _selectedFiles.clear();
  }
  
  // 获取文件图标
  String getFileIcon(VirtualFileNode node) {
    if (node.isFolder) {
      return 'folder';
    }
    
    final extension = path.extension(node.name).toLowerCase();
    switch (extension) {
      case '.jpg':
      case '.jpeg':
      case '.png':
      case '.gif':
      case '.bmp':
      case '.webp':
        return 'image';
      case '.mp4':
      case '.avi':
      case '.mov':
      case '.wmv':
      case '.flv':
      case '.mkv':
        return 'video';
      case '.mp3':
      case '.wav':
      case '.flac':
      case '.aac':
      case '.ogg':
        return 'audio';
      case '.pdf':
        return 'pdf';
      case '.doc':
      case '.docx':
        return 'word';
      case '.xls':
      case '.xlsx':
        return 'excel';
      case '.ppt':
      case '.pptx':
        return 'powerpoint';
      case '.txt':
      case '.md':
        return 'text';
      case '.zip':
      case '.rar':
      case '.7z':
      case '.tar':
      case '.gz':
        return 'archive';
      default:
        return 'file';
    }
  }
  
  // 格式化文件大小
  String formatFileSize(int bytes) {
    if (bytes < 1024) {
      return '$bytes B';
    } else if (bytes < 1024 * 1024) {
      return '${(bytes / 1024).toStringAsFixed(1)} KB';
    } else if (bytes < 1024 * 1024 * 1024) {
      return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
    } else {
      return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB';
    }
  }
  
  // 获取MIME类型
  String? getMimeType(String fileName) {
    return lookupMimeType(fileName);
  }
}